算法题——完全二叉树的底层最右节点

题目:给定一棵完全二叉树,返回最后一层的最右边的节点。

 

思路

  • 层次遍历,用一个last变量记录每次出队列的值,遍历结束之后last变量记录的就是所求节点。时间、空间复杂度都是O(N)。
  • 递归,求子树的高度:如果当前根节点为叶子节点,则返回;如果左子树高度>右子树高度,则在左子树继续递归过程;否则在右子树继续递归。由于是完全二叉树,求高度时只需一直往左遍历即可。每次递归都下降一层,每次都求树的高度,时间复杂度为O(lgN * lgN)。

 

代码

1 递归版:

 1 TreeNode *getLastNode(TreeNode *root)
 2 {
 3     if(root == NULL || root->left == NULL)    //递归出口,如果根为空,或者根为叶子节点。完全二叉树只需判定左儿子是否为空即可判定是否为叶子节点
 4         return root;
 5 
 6     int lh = 0;    //左子树高度
 7     TreeNode *ptn = root->left;
 8     while(ptn != NULL)
 9     {
10         ++lh;
11         ptn = ptn->left;
12     }
13 
14     int rh = 0;  //右子树高度
15     ptn = root->right;
16     while(ptn != NULL)
17     {
18         ++rh;
19         ptn = ptn->left;
20     }
21 
22     if(lh > rh)
23         return getLastNode(root->left);
24     else
25         return getLastNode(root->right);
26 }

  

2 迭代版:

TreeNode *getLastNode(TreeNode *root)
{
    if(root == NULL)
        return NULL;

    int height = 0;  //先求树的高度
    TreeNode *ptn = root->left;
    while(ptn != NULL)
    {
        ++height;
        ptn = ptn->left;
    }

    TreeNode *last = root;
    while(last->left != NULL)  //指向叶节点时退出
    {
        int lh = --height;    //左子树的高度必然是父亲树高度-1

        int rh = 0;
        ptn = last->right;
        while(ptn != NULL)
        {
            ++rh;
            ptn = ptn->left;
        }

        if(lh > rh)
            last = last->left;
        else
            last = last->right;
    }

    return last;
}

 

posted @ 2014-08-16 22:27  阿杰的专栏  阅读(3100)  评论(0编辑  收藏  举报